package com.seeyon.apps.kkSample.utils.http;

import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * @author songhaoran3571
 * @description HTTP REST 请求帮助类
 */
public class HttpUtil {

    private static Log log = LogFactory.getLog(HttpUtil.class);

    /**
     * 向指定URL发送GET方法的请求
     *
     * @param url         地址
     * @param headerParam 请求头参数
     * @param param       参数
     * @return
     * @throws Exception
     */

    public static String doGet(String url, Map<String, Object> headerParam, Map<String, Object> param) {

        // 创建Httpclient对象
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            // 创建uri
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key).toString());
                }
            }
            URI uri = builder.build();

            // 创建http GET请求
            HttpGet httpGet = new HttpGet(URLDecoder.decode(uri.toString(), "UTF-8"));
//            HttpGet httpGet = new HttpGet(uri);
            if (headerParam != null) {
                for (String key : headerParam.keySet()) {
                    httpGet.addHeader(key, headerParam.get(key).toString());
                }
            }

            // 执行请求
            response = httpclient.execute(httpGet);
            // 判断返回状态是否为200
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                //获取response的body部分
                HttpEntity entity = response.getEntity();
                //读取reponse的body部分并转化成字符串
                resultString = EntityUtils.toString(entity);
            }
            log.info("返回值：" + resultString);
            return resultString;


        } catch (Exception e) {
            log.info("shkk:httpGET请求异常：" + e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                log.error("shkk:httpClient关闭异常：" + e);
            }
        }
        return null;
    }


    /**
     * 向指定URL发送GET方法的请求
     *
     * @param url         地址
     * @param headerParam 请求头参数
     * @param param       参数
     * @return
     * @throws Exception
     */

    public static String doPut(String url, Map<String, Object> headerParam, Map<String, Object> param, File file) {

        log.info("shkk：地址 doPut" + url);
        log.info("shkk：请求头 doPut" + headerParam);
        log.info("shkk：参数 doPut" + param);
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPut put = new HttpPut(url);
        List<NameValuePair> content = new ArrayList<NameValuePair>();
        //装填参数
        if (param != null) {
            String paramsStr = JSONObject.toJSONString(param);
            StringEntity entity = new StringEntity(paramsStr, "UTF-8");
            entity.setContentType("application/json");
            put.setEntity(entity);
        }

        CloseableHttpResponse response = null;
        try {
            if (headerParam != null) {
                //循环增加header
                Iterator headerIterator = headerParam.entrySet().iterator();
                while (headerIterator.hasNext()) {
                    Entry<String, String> elem = (Entry<String, String>) headerIterator.next();
                    put.addHeader(elem.getKey(), elem.getValue());
                }
            }

            if (file != null) {

                String boundary = "----shkk";
//HttpEntity builder
                MultipartEntityBuilder builder = MultipartEntityBuilder.create();
                //字符编码
                builder.setCharset(Charset.forName("UTF-8"));
                //模拟浏览器
                builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
                //boundary
                builder.setBoundary(boundary);
                //multipart/form-data
//			builder.addPart("multipartFile",new FileBody(filePath));
                // binary
                builder.addBinaryBody("name=\"multipartFile\"; filename=\"test.docx\"", new FileInputStream(file), ContentType.MULTIPART_FORM_DATA, file.getName());// 文件流
//            //其他参数
//            builder.addTextBody("filename", fileName,  ContentType.create("text/plain", Consts.UTF_8));
                //HttpEntity
                HttpEntity entity = builder.build();
                put.setEntity(entity);
            }

            if (content.size() > 0) {
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(content, "UTF-8");
                put.setEntity(entity);
            }
            log.info("请求地址：" + url);
            log.info("请求参数：" + param.toString());

            //执行请求操作，并拿到结果（同步阻塞）
            response = httpClient.execute(put);
            //获取结果实体
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                //获取response的body部分
                HttpEntity entity = response.getEntity();
                //读取reponse的body部分并转化成字符串
                result = EntityUtils.toString(entity);
            }
            log.info("返回值：" + result);
            return result;
        } catch (IOException e) {
            log.info("shkk:httpPUT请求异常：" + e);
        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                log.error("shkk:httpClient关闭异常：" + e);
            }

        }
        return null;
    }

    /**
     * 向指定URL发送post方法的请求
     *
     * @param url         地址
     * @param headerParam 请求头参数
     * @param param       参数
     * @return
     * @throws Exception
     */

    public static String doPost(String url, Map<String, Object> headerParam, Map<String, Object> param) {

        log.info("shkk：地址 doPost" + url);
        log.info("shkk：请求头 doPost" + headerParam);
        log.info("shkk：参数 doPost" + param);
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        //装填参数
        if (param != null) {
            String paramsStr = JSONObject.toJSONString(param);
            StringEntity entity = new StringEntity(paramsStr, "UTF-8");
            entity.setContentType("application/json");
            post.setEntity(entity);
        }

        CloseableHttpResponse response = null;
        try {
            if (headerParam != null) {
                for (String key : headerParam.keySet()) {
                    log.info(key + "    -----  " + headerParam.get(key));
                    post.addHeader(key, headerParam.get(key).toString());
                }
            }

            //执行请求操作，并拿到结果（同步阻塞）
            response = httpClient.execute(post);
            //获取结果实体
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                //获取response的body部分
                HttpEntity entity = response.getEntity();
                //读取reponse的body部分并转化成字符串
                result = EntityUtils.toString(entity);
            }
            log.info("返回值：" + result);
            return result;
        } catch (IOException e) {
            log.info("shkk:httpPOST请求异常：" + e);
        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                log.error("shkk:httpClient关闭异常：" + e);
            }

        }
        return null;
    }


    /**
     * 向指定URL发送post方法的请求
     *
     * @param url         地址
     * @param headerParam 请求头参数
     * @param param       参数
     * @return
     * @throws Exception
     */

    public static String doPost(String url, Map<String, Object> headerParam, String param) {
        log.info("==============doPost：地址" + url);
        log.info("==============doPost：请求头" + headerParam);
        log.info("==============doPost：参数" + param);
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        //装填参数
        if (param != null) {
            StringEntity entity = new StringEntity(param, "UTF-8");
            entity.setContentType("application/json");
            post.setEntity(entity);
        }

        CloseableHttpResponse response = null;
        try {
            if (headerParam != null) {
                for (String key : headerParam.keySet()) {
                    post.addHeader(key, headerParam.get(key).toString());
                }
            }
            //执行请求操作，并拿到结果（同步阻塞）
            response = httpClient.execute(post);
            log.info("==============doPost response 返回值：" + response);
            //获取结果实体
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                //获取response的body部分
                HttpEntity entity = response.getEntity();
                //读取reponse的body部分并转化成字符串
                result = EntityUtils.toString(entity);
            }
            log.info("==============doPost 返回值：" + result);
            return result;
        } catch (IOException e) {
            log.info("==============doPost:请求异常：",e);
        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                log.error("shkk:httpClient关闭异常：" + e);
            }

        }
        return null;
    }

    /**
     * @param url        访问地址
     * @param headerMap  header 参数；可以通过下面工具类将string类型转换成map
     * @param contentMap 需要传输参数参数；对象可以通过json转换成map
     * @return 返回网页返回的数据
     */
    public static String postMap(String url, Map<String, Object> headerMap, Map<String, Object> contentMap) {
        log.info("shkk：请求" + url);
        log.info("shkk：请求头" + headerMap);
        log.info("shkk：参数" + contentMap);
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        List<NameValuePair> content = new ArrayList<NameValuePair>();
        //将content生成entity
        if (contentMap != null) {
            Iterator iterator = contentMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<String, String> elem = (Entry<String, String>) iterator.next();
                content.add(new BasicNameValuePair(elem.getKey(), elem.getValue()));
            }
        }
        CloseableHttpResponse response = null;
        try {
            if (headerMap != null) {
                //循环增加header
                Iterator headerIterator = headerMap.entrySet().iterator();
                while (headerIterator.hasNext()) {
                    Entry<String, String> elem = (Entry<String, String>) headerIterator.next();
                    post.addHeader(elem.getKey(), elem.getValue());
                }
            }

            if (content.size() > 0) {
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(content, "UTF-8");
                post.setEntity(entity);
            }
            //发送请求并接收返回数据
            response = httpClient.execute(post);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                //获取response的body部分
                HttpEntity entity = response.getEntity();
                //读取reponse的body部分并转化成字符串
                result = EntityUtils.toString(entity);
            }
            log.info("shkk:请求返回值：" + response);
            return result;
        } catch (IOException e) {
            log.error("shkk:请求异常：" + e);

        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                log.error("shkk:httpClient关闭异常：" + e);
            }

        }
        return null;
    }


    /**
     * @param url        访问地址
     * @param contentMD5 header 参数；可以通过下面工具类将string类型转换成map
     * @param file       需要传输参数参数；对象可以通过json转换成map
     * @return 返回网页返回的数据
     */
    public static String putFile(String url, String contentMD5, File file) {
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();

        MediaType mediaType = MediaType.parse("application/pdf");
        RequestBody body = RequestBody.create(mediaType, file);
        Request request = new Request.Builder()
                .url(url)
                .method("PUT", body)
                .addHeader("Content-MD5", contentMD5)
                .addHeader("Content-Type", "application/pdf")
                .build();
        try {
            Response response = client.newCall(request).execute();
            if (response != null && response.code() == 200) {
                //获取response的body部分
                return response.body().string();
            }
            log.info(response);

        } catch (IOException e) {
            log.error("E签宝-PUT上传文件失败 {}:" + e);
        }
        return null;
    }

    public static String getMethod(String url) {
        StringBuffer sb = new StringBuffer();
        try {
            URL restURL = new URL(url);

            HttpURLConnection conn = (HttpURLConnection) restURL.openConnection();

            conn.setRequestMethod("GET"); // POST GET PUT DELETE
            conn.setRequestProperty("Accept", "application/json");
//		conn.setRequestProperty("appID", "4916EBDE5F324B1FB05408847F94AF1E");
//		conn.setRequestProperty("keySecret", "797C9A2E449E40EDB57449C7BAA161F8");

            conn.setReadTimeout(5000);
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            br.close();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return sb.toString();
    }
}
